package com.shinektv.vod.ksclib;

import android.text.TextUtils;
import android.util.Log;

import com.shinektv.vod.ksclib.impl.SongScheduleListener;

import java.util.ArrayList;
import java.util.List;

public class KscFile {

    private static final String TAG = KscFile.class.getSimpleName();

    //歌词
    public static final String SCHEDULE_WORDS_OF_SONG_START = "SCHEDULE_WORDS_OF_SONG_START";
    public static final String SCHEDULE_WORDS_OF_SONG_STOP = "SCHEDULE_WORDS_OF_SONG_STOP";
    //副歌
    public static final String SCHEDULE_CHORUS_START = "SCHEDULE_CHORUS_START";
    public static final String SCHEDULE_CHORUS_STOP = "SCHEDULE_CHORUS_STOP";
    //过场
    public static final String SCHEDULE_INTERLUDE_START = "SCHEDULE_INTERLUDE_START";
    public static final String SCHEDULE_INTERLUDE_STOP = "SCHEDULE_INTERLUDE_STOP";
    //结尾（尾声）
    public static final String SCHEDULE_EPILOGUE_START = "SCHEDULE_EPILOGUE_START";
    //计算过场时间间隔
    public static final int INTERLUDE_TIME = 8000;

    /***
     * ksc文件路径
     */
    private String file_path = "";
    /**
     * 歌曲名称
     */
    private String song_name = "";
    /**
     * 歌星名称
     */
    private String singer_name = "";
    /**
     * 行数
     */
    private int rows = 2;
    /**
     * 副歌开始时间
     */
    private long sing_start = -1;
    /**
     * 副歌结束时间
     */
    private long sing_stop = -1;
    private List<Integer> singStarts = new ArrayList<>();
    private List<Integer> singStops = new ArrayList<>();

    private List<Long[]> interludeList = new ArrayList<>();
    /**
     * 是否有副歌
     */
    private boolean has_refrain = false;
    /**
     * ksc行信息
     */
    private List<KscLine> kscLines = new ArrayList<>();

    private String curKscStatue = "";


    private IReadTextFile mIReadTextFile = null;

    /**
     * 解析ksc文件
     *
     * @param ksc_path
     * @return
     */
    public boolean open(final String ksc_path, IReadTextFile readTextFile) {
        this.file_path = ksc_path;
        if (!kscLines.isEmpty()) {
            kscLines.clear();
        }

        mIReadTextFile = readTextFile;
        singStarts.clear();
        singStops.clear();
        interludeList.clear();
        curKscStatue = "";
        has_refrain = false;
        refrainEndTime = -1;
        Log.i(TAG, "解析ksc文件，所有缓存清空重置");
        return parse();
    }

    public void printString() {
        Log.i(TAG, "歌曲名称：" + song_name);
        Log.i(TAG, "歌星名称：" + singer_name);
//        Log.i(TAG, "副歌开始时间：" + sing_start);
//        Log.i(TAG, "副歌结束时间：" + sing_stop);

        int size = Math.min(singStarts.size(), singStops.size());
        for (int i = 0; i < size; i++) {
            String str = "副歌开始：" + singStarts.get(i);
            Log.i(TAG, str);
            String stop = "副歌结束：" + singStops.get(i);
            Log.i(TAG, stop);
        }

        for (KscLine line : kscLines) {
            line.printString();
        }
        Log.i(TAG, "副歌集合：" + singStarts.size() + "___" + singStarts + "__" + singStops);
        Log.i(TAG, "过场集合：" + interludeList.size() + "__" + interludeList);
    }

    public List<KscLine> getKscLines() {
        return kscLines;
    }

    /**
     * 是否解析成功，只有ksc中有歌词才会认为成功
     *
     * @return
     */
    public boolean succeed() {
        return !kscLines.isEmpty();
    }

    /**
     * 解析文件每行数据
     *
     * @return
     */
    private boolean parse() {

        if (mIReadTextFile == null)
            mIReadTextFile = new DefaultReadTextFile();

        List<String> lines = mIReadTextFile.ReadTxtFile(this.file_path);

        for (String line : lines) {
            try {
                Log.i(TAG, "parse: 1111111111111  " + line);
                parse_line(line);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (singStarts.size() != singStops.size()) {
            Log.d(TAG, "chorus analysis fail! ");
        } else {
            int size = singStarts.size();
            if (size == 0) {
                Log.d(TAG, "There is no chorus! ");
            } else {
                has_refrain = true;
            }
        }

        return kscLines.size() > 0;
    }

    /**
     * 找到字符串中第一个连续数字
     *
     * @param text
     * @return
     */
    String findFirstNumber(final String text) {
        String result = "";

        for (int i = 0; i < text.length(); i++) {
            if (text.charAt(i) >= '0' && text.charAt(i) <= '9') {

                result = result.concat(text.charAt(i) + "");
            } else {
                if (result.length() > 0)
                    break;
            }

        }

        return result;
    }

    /**
     * 解析每行的内容
     *
     * @param line_lrc 行文本
     */
    private void parse_line(final String line_lrc) {
        String upperString = line_lrc.toUpperCase();
        if (upperString.startsWith("KARAOKE.ADD")) {
            String line = line_lrc;
            int pos = line.indexOf("'");

            if (pos != -1) {
                line = line.substring(pos + 1);
                //00:34.627', '00:38.705', '闭上眼睛忍住呼吸', '374,434,367,367,500,601,601,834');"
                pos = line.indexOf("'");
                if (pos == -1)
                    return;
                //00:34.627
                String start_time = line.substring(0, pos);

                //, '00:38.705', '闭上眼睛忍住呼吸', '374,434,367,367,500,601,601,834');
                line = line.substring(pos + 1);
                pos = line.indexOf("'");
                if (pos == -1)
                    return;
                //00:38.705', '闭上眼睛忍住呼吸', '374,434,367,367,500,601,601,834')
                line = line.substring(pos + 1);
                pos = line.indexOf("'");
                if (pos == -1)
                    return;
                String end_time = line.substring(0, pos);
                //, '闭上眼睛忍住呼吸', '374,434,367,367,500,601,601,834');
                line = line.substring(pos + 1);

                //找文字的节点
                pos = line.lastIndexOf("'");
                if (pos == -1)
                    return;
                //, '闭上眼睛忍住呼吸', '374,434,367,367,500,601,601,834
                line = line.substring(0, pos);
                pos = line.lastIndexOf("'");
                if (pos == -1)
                    return;
                String wordtimes = line.substring(pos + 1);
                line = line.substring(0, pos);

                pos = line.indexOf("'");
                if (pos == -1)
                    return;
                line = line.substring(pos + 1);
                pos = line.lastIndexOf("'");
                if (pos == -1)
                    return;
                line = line.substring(0, pos);
                String linetext = line;

                if (start_time.isEmpty() || end_time.isEmpty() || linetext.isEmpty() || wordtimes.isEmpty())
                    return;

                KscLine lineinfo = new KscLine();
                lineinfo.init(kscLines.size(), start_time, end_time, linetext, wordtimes);

                if (kscLines.size() > 0) {
                    KscLine ksc = kscLines.get(kscLines.size() - 1);
                    if (lineinfo.getLine_start_time() - ksc.getLine_stop_time() >= INTERLUDE_TIME) {
                        Long[] interlude = new Long[2];
                        interlude[0] = ksc.getLine_stop_time();
                        interlude[1] = lineinfo.getLine_start_time();
                        interludeList.add(interlude);
                    }
                }

                kscLines.add(lineinfo);
            }
        } else if (upperString.startsWith("KARAOKE.SONGNAME")) {
            //歌曲名称
            //Karaoke.songname : = '绝口不提爱你';
            int pos = line_lrc.indexOf("'");
            int endpos = line_lrc.lastIndexOf("'");
            if (pos == -1 || endpos == -1)
                return;
            String songname = line_lrc.substring(pos + 1, endpos);
            this.song_name = songname;
        } else if (upperString.startsWith("KARAOKE.SINGER")) {
            //歌星名称
            //Karaoke.singer : = '郑中基';
            int pos = line_lrc.indexOf("'");
            int endpos = line_lrc.lastIndexOf("'");
            String singername = line_lrc.substring(pos + 1, endpos);
            this.singer_name = singername;
        } else if (upperString.startsWith("KARAOKE.SING_START")) {
            //副歌开始时间
            //Karaoke.sing_start : = 208;
            String sing_start = findFirstNumber(line_lrc);
            this.sing_start = Integer.parseInt(sing_start);
            singStarts.add(Integer.parseInt(sing_start));
        } else if (upperString.startsWith("KARAOKE.SING_STOP")) {
            //副歌结束时间
            //Karaoke.sing_stop : = 260;
            String sing_stop = findFirstNumber(line_lrc);
            this.sing_stop = Integer.parseInt(sing_stop);
            singStops.add(Integer.parseInt(sing_stop));
        } else if (upperString.startsWith("KARAOKE.ROWS")) {
            String rows = findFirstNumber(line_lrc);
            this.rows = Integer.parseInt(rows);

        } else {

        }
    }

    SongScheduleListener mScheduleListener;

    public void setScheduleListener(SongScheduleListener listener) {
        mScheduleListener = listener;
    }

    public boolean isHasRefrain() {
        return has_refrain;
    }

    /**
     * 获取中间的副歌
     *
     * @return
     */
    public long[] getChorus() {
        if (!has_refrain) {
            return null;
        }
        int size = singStarts.size();
        long[] chorus = new long[2];
        if (size == 1) {
            chorus[0] = singStarts.get(0) * 1000;
            chorus[1] = singStops.get(0) * 1000;
        } else if (size == 2) {
            chorus[0] = singStarts.get(1) * 1000;
            chorus[1] = singStops.get(1) * 1000;
        } else {
            int middle = size / 2;
            chorus[0] = singStarts.get(middle) * 1000;
            chorus[1] = singStops.get(middle) * 1000;
        }
        return chorus;
    }

    private long refrainEndTime = -1;

    //当选择只唱副歌的时候，调这个方法设置副歌结束时间
    public void setRefrainEndTime(long l) {
        refrainEndTime = l;
    }

    public long getRefrainEndTime() {
        return refrainEndTime;
    }

    /**
     * 跳过前奏
     *
     * @return 获取第一句歌词的开始时间
     */
    public long firstWordsOfSong() {
        if (kscLines.size() > 0) {
            return kscLines.get(0).getLine_start_time();
        }
        return -1;
    }

    /**
     * 获取副歌集合
     *
     * @return
     */
    public List<Long[]> getRefrain() {
        if (has_refrain) {
            List<Long[]> refrains = new ArrayList<>();
            for (int i = 0; i < singStarts.size(); i++) {
                Long[] ref = new Long[2];
                ref[0] = (long) (singStarts.get(i) * 1000);
                ref[1] = (long) (singStops.get(i) * 1000);
                refrains.add(ref);
            }
            return refrains;
        }
        return null;
    }

    /**
     * 获取播放进度，歌曲开始、歌词开始、副歌开始、过长开始。。。
     *
     * @param ms 演唱进度
     */
//    public String getSongSchedule(long ms) {
//        if (kscLines.size() <= 0) {
//            //没有歌词，
//            return null;
//        }
//        String schedule = "";
//        //还未标记过状态，只要标记过任何一个后就不需要进去了
//        if (TextUtils.isEmpty(curKscStatue)) {
//            //
//            KscLine kscLine = kscLines.get(0);
//            if (kscLine.getLine_start_time() <= ms && kscLine.getLine_stop_time() > ms) {
//                schedule = SCHEDULE_WORDS_OF_SONG_START;
//            }
//        }
//        //不会发送歌词结束通知了，歌词结束时发送 结尾开始：SCHEDULE_EPILOGUE_START
////        if (ms >= kscLines.get(kscLines.size() - 1).getLine_stop_time()) {
////            schedule = SCHEDULE_WORDS_OF_SONG_STOP;
////        }
//
//        //副歌部分
//        if (has_refrain) {
//            int size = singStarts.size();
//            int index = -1;
//            for (int i = 0; i < size; i++) {
//                if (singStarts.get(i) * 1000 <= ms && singStops.get(i) * 1000 > ms) {
//                    index = i;
//                    schedule = SCHEDULE_CHORUS_START;
//                    break;
//                }
//            }
//            //如果当前副歌一开始，并且没有重新
//            if (curKscStatue.equals(SCHEDULE_CHORUS_START) && index == -1) {
//                schedule = SCHEDULE_CHORUS_STOP;
//            }
//        }
//
//        //过场部分
//        if (!schedule.equals(SCHEDULE_CHORUS_START) && !curKscStatue.equals(SCHEDULE_CHORUS_START)) {
//            int index = -10;
//            if (curKscStatue.equals(SCHEDULE_INTERLUDE_START)) {
//                index = -1;
//            }
//            for (int i = 0; i < interludeList.size(); i++) {
//                if (ms >= interludeList.get(i)[0] && ms < interludeList.get(i)[1]) {
//                    index = i;
//                    schedule = SCHEDULE_INTERLUDE_START;
//                    break;
//                }
//            }
//            if (index == -1) {
//                schedule = SCHEDULE_INTERLUDE_STOP;
//            }
//        }
//
//        //结尾开始
//        if (has_refrain) {
//            if (ms > Math.max(kscLines.get(kscLines.size() - 1).getLine_stop_time(), singStops.get(singStops.size() - 1))) {
//                schedule = SCHEDULE_EPILOGUE_START;
//            }
//        } else if (ms > kscLines.get(kscLines.size() - 1).getLine_stop_time()) {
//            schedule = SCHEDULE_EPILOGUE_START;
//        }
//        curKscStatue = schedule;
////        Log.i(TAG, "___" + ms+"_____"+schedule);
//        if (null != mScheduleListener) {
//            mScheduleListener.onSchedule(schedule);
//        }
//        return schedule;
//    }
    public void songSchedule(long ms) {
        if (ms <= 0) {
            return;
        }
        if (kscLines.size() <= 0) {
            //没有歌词，
            return;
        }
        String schedule = "";
        //还未标记过状态，只要标记过任何一个后就不需要进去了
        if (TextUtils.isEmpty(curKscStatue)) {
            //
            KscLine kscLine = kscLines.get(0);
            if (kscLine.getLine_start_time() <= ms && kscLine.getLine_stop_time() > ms) {
                schedule = SCHEDULE_WORDS_OF_SONG_START;
                Log.i(TAG, "__ksc__");
            }
        }
        //不会发送歌词结束通知了，歌词结束时发送 结尾开始：SCHEDULE_EPILOGUE_START
//        if (ms >= kscLines.get(kscLines.size() - 1).getLine_stop_time()) {
//            schedule = SCHEDULE_WORDS_OF_SONG_STOP;
//        }

        //副歌部分
        if (has_refrain) {
            int size = singStarts.size();
            int index = -1;
            for (int i = 0; i < size; i++) {
                if (singStarts.get(i) * 1000 <= ms && singStops.get(i) * 1000 > ms) {
                    index = i;
                    schedule = SCHEDULE_CHORUS_START;
                    break;
                }
            }
            //如果当前副歌一开始，并且没有重新
            if (curKscStatue.equals(SCHEDULE_CHORUS_START) && index == -1) {
                schedule = SCHEDULE_CHORUS_STOP;
            }
        }

        //过场部分
        if (!schedule.equals(SCHEDULE_CHORUS_START) && !curKscStatue.equals(SCHEDULE_CHORUS_START)) {
            int index = -10;
            if (curKscStatue.equals(SCHEDULE_INTERLUDE_START)) {
                index = -1;
            }
            for (int i = 0; i < interludeList.size(); i++) {
                if (ms >= interludeList.get(i)[0] && ms < interludeList.get(i)[1]) {
                    index = i;
                    schedule = SCHEDULE_INTERLUDE_START;
                    break;
                }
            }
            if (index == -1) {
                schedule = SCHEDULE_INTERLUDE_STOP;
            }
        }

        //结尾开始
        if (has_refrain) {
            if (ms > Math.max(kscLines.get(kscLines.size() - 1).getLine_stop_time(), singStops.get(singStops.size() - 1))) {
                schedule = SCHEDULE_EPILOGUE_START;
            }
        } else if (ms > kscLines.get(kscLines.size() - 1).getLine_stop_time()) {
            schedule = SCHEDULE_EPILOGUE_START;
        }
        curKscStatue = schedule;
        if (null != mScheduleListener) {
            mScheduleListener.onSchedule(schedule);
        }
    }
}
